package jpacman.model;

/**
 * Class to represent the effects of moving a monster.
 *
 * @author Exercise 52
 * @version 1
 */
public class MonsterMove extends Move {

	
	/**
     * The monster wishing to move.
     */
    private final Monster theMonster;
	
	/**
     * Create a move for the given monster to a given target cell.
     *
     * @param monster
     *            the Monster to be moved
     * @param toCell
     *            the target location.
     * @see jpacman.model.Move
     */
	public MonsterMove(Monster monster, Cell toCell) {
		// preconditions checked in super method.
		super(monster, toCell);
		theMonster = monster;
		precomputeEffects();
	    assert invariant();
	}

	/**
	 * 
     * @return true iff the invariant holds.
     */
    public final boolean invariant() {
        return moveInvariant() &&  theMonster != null
        && getMovingGuest().equals(theMonster);
    }
    
    
    /**
     * Return the Monster initiating this move.
     * @return The moving monster.
     */
    public Monster getMonster() {
        assert invariant();
        return theMonster;
    }
    
    /**
     * Attempt to move the Monster towards a target guest.
     * @param targetGuest The guest that the Monster will meet.
     * @return true if the move is possible, false otherwise.
     * @see jpacman.model.Move#tryMoveToGuest(jpacman.model.Guest)
     */
	@Override
	protected boolean tryMoveToGuest(Guest targetGuest) {
		assert tryMoveToGuestPrecondition(targetGuest)
        : "percolated precondition";
		return targetGuest.meetMonster(this);
	}
	
	/**
     * Undo the monstermove.
     * 
     */
	@Override
	protected void undo() {
		assert invariant();
		assert canUndo() : "MonsterMove has to be applied before it can be undone";
		if (!this.playerWillDie()) {
	    	MonsterMove undoMove = new MonsterMove(theMonster, getDepartureCell());
	    	undoMove.apply();
	    	setCanUndoFalse();
	    	assert !canUndo();
	    	assert invariant();
		}
    }

}
